package com.qfmy.common.result;

import lombok.Data;

import java.io.Serializable;


/**
 * @author 清风明月
 * @Package com.qfmy.common.exception
 * @date 2025/9/9
 * @description 全局统一返回结果类
 */
@Data
@SuppressWarnings("all")
public class Result<T> implements Serializable {

    /**
     * 响应状态码
     * 用于标识请求处理结果：
     * - 成功状态码：如200（通常对应ResultCodeEnum.SUCCESS）
     * - 失败状态码：如500（系统错误）、400（参数错误）等（通过ResultCodeEnum定义）
     * 前端可根据该码快速判断请求结果类型，无需解析message
     */
    private Integer code;

    /**
     * 响应消息
     * 用于描述请求处理的详细信息：
     * - 成功时：通常为"success"或具体操作结果描述
     * - 失败时：包含错误原因（如"用户名已存在"、"权限不足"等）
     * 主要用于前端展示给用户或开发调试
     */
    private String message;

    /**
     * 响应数据
     * 用于携带请求成功时的业务数据（如查询的用户信息、列表数据等）
     * 失败时通常为null
     */
    private T data;

    /**
     * 无参构造方法
     * 用于JSON反序列化或其他需要默认构造的场景（如框架反射实例化）
     */
    public Result() {
    }

    /**
     * 私有工具方法：构建基础响应对象并设置数据
     * 封装创建Result实例的逻辑，避免重复代码
     * @param data 响应数据
     * @param <T>  数据类型
     * @return 基础响应对象（仅包含数据，状态码和消息需后续设置）
     */
    private static <T> Result<T> build(T data) {
        Result<T> result = new Result<>();
        if (data != null)
            result.setData( data);
        return result;
    }

    /**
     * 构建响应对象（根据枚举设置状态码和消息）
     * 核心构建方法，通过ResultCodeEnum统一管理状态码和消息，确保规范
     * @param body           响应数据
     * @param resultCodeEnum 包含状态码和消息的枚举（如SUCCESS、FAIL、PARAM_ERROR等）
     * @param <T>            数据类型
     * @return 完整的响应对象（包含数据、状态码、消息）
     */
    public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
        Result<T> result = build(body); // 先构建基础对象并设置数据
        result.setCode(resultCodeEnum.getCode()); // 从枚举获取状态码
        result.setMessage(resultCodeEnum.getMessage()); // 从枚举获取消息
        return result;
    }

    /**
     * 快捷方法：返回成功响应（带数据）
     * 简化成功场景的响应构建，默认使用ResultCodeEnum.SUCCESS的状态码和消息
     * @param data 成功时返回的业务数据
     * @param <T>  数据类型
     * @return 成功响应对象（code=成功码，message=成功消息，data=业务数据）
     */
    public static <T> Result<T> ok(T data) {
        return build(data, ResultCodeEnum.SUCCESS);
    }

    /**
     * 快捷方法：返回成功响应（无数据）
     * 适用于不需要返回业务数据的成功场景（如新增、删除操作）
     * @param <T> 数据类型（实际为null，泛型仅为保持类型一致性）
     * @return 成功响应对象（code=成功码，message=成功消息，data=null）
     */
    public static <T> Result<T> ok() {
        return Result.ok(null); // 调用带数据的ok方法，传入null
    }

    /**
     * 快捷方法：返回失败响应（默认失败）
     * 适用于通用失败场景，默认使用ResultCodeEnum.FAIL的状态码和消息（如系统异常）
     * @param <T> 数据类型（实际为null）
     * @return 失败响应对象（code=默认失败码，message=默认失败消息，data=null）
     */
    public static <T> Result<T> fail() {
        return build(null, ResultCodeEnum.FAIL);
    }

    /**
     * 快捷方法：返回失败响应（自定义状态码和消息）
     * 适用于需要自定义错误信息的场景（如特定业务校验失败）
     * @param code    自定义失败状态码
     * @param message 自定义失败消息
     * @param <T>     数据类型（实际为null）
     * @return 失败响应对象（code=自定义码，message=自定义消息，data=null）
     */
    public static <T> Result<T> fail(Integer code, String message) {
        Result<T> result = build(null); // 构建基础对象（无数据）
        result.setCode(code); // 设置自定义状态码
        result.setMessage(message); // 设置自定义消息
        return result;
    }


}